home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1995 April / Internet Tools.iso / infoserv / gopher / Unix / gopher-gateways / techinfo / techinpher / v1.0 / inet.c.Z / inet.c
Encoding:
C/C++ Source or Header  |  1993-01-20  |  6.1 KB  |  269 lines

  1. /*
  2.  *------------------------------------------------------------------
  3.  *
  4.  * $Source: /afs/net.mit.edu/dapps/project/techinfodev/src/srv_ti/RCS/inet.c,v $
  5.  * $Revision: 1.3 $
  6.  * $Date: 92/08/28 16:09:10 $
  7.  * $State: Exp $
  8.  * $Author: ark $
  9.  * $Locker: ark $
  10.  *
  11.  * $Log:    inet.c,v $
  12.  * Revision 1.3  92/08/28  16:09:10  ark
  13.  * Summer 1992 final version
  14.  * 
  15.  * Revision 1.2  92/08/04  16:26:38  ark
  16.  * Test production version 8/4/92
  17.  * 
  18.  * Revision 1.1  92/07/22  11:09:01  ark
  19.  * Saber loads quietly; ANSI use standardized; command line options; no behavioral changes
  20.  * 
  21.  * Revision 1.0  92/07/10  12:32:11  ark
  22.  * Initial revision
  23.  * 
  24.  * Revision 1.1  91/07/15  10:40:15  thorne
  25.  * Initial revision
  26.  * 
  27.  *------------------------------------------------------------------
  28.  */
  29.  
  30. #ifndef lint
  31. #ifndef SABER
  32. static char *rcsid_foo_c = "$Header: /afs/net.mit.edu/dapps/project/techinfodev/src/srv_ti/RCS/inet.c,v 1.3 92/08/28 16:09:10 ark Exp Locker: ark $";
  33. #endif SABER
  34. #endif  lint
  35. /*
  36.  * inet.c:    Code for internet socket manipulations.
  37.  */
  38. /*
  39.   Copyright (C) 1989 by the Massachusetts Institute of Technology
  40.  
  41.    Export of this software from the United States of America is assumed
  42.    to require a specific license from the United States Government.
  43.    It is the responsibility of any person or organization contemplating
  44.    export to obtain such a license before exporting.
  45.  
  46. WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
  47. distribute this software and its documentation for any purpose and
  48. without fee is hereby granted, provided that the above copyright
  49. notice appear in all copies and that both that copyright notice and
  50. this permission notice appear in supporting documentation, and that
  51. the name of M.I.T. not be used in advertising or publicity pertaining
  52. to distribution of the software without specific, written prior
  53. permission.  M.I.T. makes no representations about the suitability of
  54. this software for any purpose.  It is provided "as is" without express
  55. or implied warranty.
  56.  
  57. */
  58.  
  59. #include <stdio.h>
  60. #include <sys/types.h>
  61. #include <sys/socket.h>
  62. #include <netinet/in.h>
  63. #include <netdb.h>
  64. #include <fcntl.h>
  65. #include <ctype.h>
  66. #include <arpa/inet.h> /* for rt */
  67.  
  68. #include "inet.h"
  69.  
  70. /*
  71.  * Create a socket and establish a connection over it to the given host and
  72.  * port.  Returns the (connected) socket created, or -1 in case of error.
  73.  */
  74. static    struct sockaddr_in    lsname; /* the listener */
  75. /* ARGSUSED */
  76. int
  77. inet_establish_connection(char *hostname, char *portname, int quiet)
  78. {
  79.     struct sockaddr_in    sname;
  80.     struct hostent        *hp;
  81.     struct servent        *sp;
  82.     int    sock, portnum;
  83.  
  84.     /*
  85.      * resolve hostname
  86.      */
  87.  
  88.     hp = gethostbyname(hostname);
  89.     if (hp == NULL) {
  90.         fprintf(stderr, "unknown host %s\n", hostname);
  91.         return -1;
  92.     }
  93.  
  94.     /*
  95.      * resolve portname
  96.      */
  97.  
  98.     if (isdigit(*portname))
  99.         portnum = htons(atoi(portname));/***/
  100.     else {
  101.         sp = getservbyname(portname, "tcp");
  102.         if (sp == NULL) {
  103.             fprintf(stderr, "unknown port %s\n", portname);
  104.             return -1;
  105.         }
  106.         portnum = sp->s_port;
  107.         portname = sp->s_name;
  108.     }
  109.  
  110.     /*
  111.      * build server socket name
  112.      */
  113.  
  114.     bzero(&sname, sizeof(sname));
  115.     sname.sin_family = AF_INET;
  116.     bcopy(hp->h_addr, &sname.sin_addr, hp->h_length);
  117.     sname.sin_port = portnum;
  118.  
  119.     /*
  120.      * create a network socket
  121.      */
  122.  
  123.     sock = socket(PF_INET, SOCK_STREAM, 0);
  124.  
  125.     if (sock < 0) {
  126.         perror("socket");
  127.         return -1;
  128.     }
  129.  
  130.     /*
  131.      * make a connection to the specified server on the socket
  132.      */
  133.  
  134.     if (connect(sock, &sname, sizeof(sname)) < 0) {
  135.       /*
  136.         if (!quiet)
  137.           perror("connect in inet.c"); 
  138.       */
  139.         return -1;
  140.     }
  141.       /*  if (fcntl(sock, F_SETFL, O_FSYNC) == -1)
  142.         perror("fcntl");  test for write synch */
  143.     /*
  144.     if (!quiet)
  145.         printf("Connected to %s, port %s (%d).\n",
  146.                hp->h_name, portname, ntohs(portnum)), fflush(stdout);
  147.                */
  148.     return sock;
  149. }
  150.  
  151. /*
  152.  * Create a socket bound to the given local port, and assign it
  153.  * a listening condition.
  154.  */
  155.  
  156. int
  157. inet_make_listner(int port)
  158. {
  159.  
  160.     int            sock, length, i,rc;
  161.  
  162.     sock = socket(PF_INET, SOCK_STREAM, 0);
  163.  
  164.     if (sock < 0) {
  165.         perror("creating socket");
  166.         return -1;
  167.     }
  168.  
  169.     /*
  170.      * build name for local socket 
  171.      */
  172.  
  173.     bzero(&lsname, sizeof(lsname));
  174.     lsname.sin_family = AF_INET;
  175.     lsname.sin_addr.s_addr = INADDR_ANY;
  176.     lsname.sin_port = ntohs(port);
  177.  
  178.     /*
  179.      * set name of local socket - ie. assign &sname to the socket name
  180.      * space 
  181.      */
  182.     i = 1; /* the ultrix code needs this for REUSEADDR to work */
  183.  
  184.         rc = setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&i,sizeof(i)); /* */
  185.     if (rc == -1)
  186.       perror("setting sockopt");
  187.     if (bind(sock, &lsname, sizeof(lsname)) < 0) {
  188.         perror("binding socket");
  189.         return -1;
  190.     }
  191.  
  192.     /*
  193.      * check the name assignment; a zero is returnd if call succeeds.
  194.      * &sname is altered.  &length indicates the amount of space pointed
  195.      * by name 
  196.      */
  197.  
  198.     length = sizeof(lsname);
  199.     if (getsockname(sock, &lsname, &length)) {
  200.         perror("getting socket name");
  201.         return -1;
  202.     }
  203.  
  204.     listen(sock, 5);
  205. /*
  206.     printf("Listening at local address %s, port %d, over socket #%d.\n\n",
  207.         inet_ntoa(lsname.sin_addr), ntohs(lsname.sin_port),
  208.         sock); 
  209. */
  210. /*****/
  211.     return sock;
  212. }
  213.  
  214. /*
  215.  * Accept a connection coming in over the given listen_sock (a socket
  216.  * that is being listend on, perhaps created by make_listner()).
  217.  * Return a new connected socket, and the contacting hostname and
  218.  * portnumber if desired and available.
  219.  */
  220.  
  221. int
  222. inet_accept_connection(int listen_sock, char **hname, int *portnum)
  223. {
  224.     struct sockaddr_in    sname;
  225.     struct hostent        *host;
  226.     int            socket, length;
  227.     
  228.     socket = accept(listen_sock, 0, 0);
  229.     if (socket < 0) {
  230.         perror("accept");
  231.         return -1;
  232.     }
  233.  
  234.     /*
  235.      * get name of other end of this connection; returns zero if call
  236.      * successful.  &sname is altered by call, &length is space pointed
  237.      * to by name 
  238.      */
  239.  
  240.     length = sizeof(sname);
  241.     if (getpeername(socket, &sname, &length))
  242.         perror("getpeername");
  243.  
  244.     if (portnum)
  245.         *portnum = ntohs(sname.sin_port);
  246.  
  247.     /*
  248.      * return a pointer to the structure hostent, which contains host
  249.      * information ie. name of host, host address type (AF_INET), length
  250.      * of address    
  251.      */
  252.  
  253.     if (hname) {
  254.         host = gethostbyaddr(&sname.sin_addr, sizeof(sname.sin_addr), AF_INET);
  255.         if (!host) {
  256.             perror("gethostbyaddr");
  257.              *hname = inet_ntoa(sname.sin_addr);
  258.             /* *hname = "<unknown>"; */
  259.         } else
  260.             *hname = host->h_name;
  261.     }
  262.  
  263.     return socket;
  264. }
  265.  
  266.  
  267.  
  268.  
  269.